BuckleScript
的基礎
如果需要對 OCaml 有興趣可以參考 官方文件
如果對 Reason 有興趣可以參考 官方文件
OCaml 的另一種語法,對 Javascript
的開發者比較親切
官方的套件管理, 自從 BuckleScript
支援 NPM/YARN 之後就不需要使用他了
都是 BuckleScript <-> JavaScript
交互編譯的術語
BuckleScript
中使用 JS 值得一種方式Foreign Function Interface
的縮寫, "external", "wrapper" 和 "interop" 的通用術語, 基本上就是在一個語言中呼叫另一個語言的值值 | bs | 意義 |
---|---|---|
val | [@bs.val] | global value |
scope | [@bs.scope] | use names as a namespace |
new | [@bs.new] | new constructor |
module | [@bs.module] | 從某一個 mobule 綁定其中一個值 |
send | @bs.send | function chaining |
send.pipe | @bs.send.pipe | function chaining includes parameters |
splice | [@bs.splice] | 具有不定長度參數的函式 |
note:這只是一小部分
Reason
中直接寫 JavascriptBucklescript
所提供的lib
[%%raw "var a = 1, b = 2"];
let add = [%raw "a + b"];
let myFunction = [%raw "(a, b) => a + b"]
Js.log(myFunction(1)(2));
Js.log({js|你好,
世界|js});
let world = "world";
let helloWorld = {j|hello, $world|j};
note: 先看看官方是否有先幫你完成的 API 再決定是否要自己處理
[@bs.val] external setTimeout/* 在 Reason 中使用的模組名稱 */: (unit => unit, int) => float = "setTimeout";/* 對應到 Javascript 中的模組名稱 */
let eventId = setTimeout(() => Js.log("hello setTimeout"), 1000);
Js.log(eventId);
亦或是利用 map
和 filter
做一些陣列處理的時候
[@bs.send] external map: (array('a), 'a => 'b) => array('b) = "";
[@bs.send] external filter: (array('a), 'a => 'b) => array('b) = "";
let mapResult = map([|1, 2, 3|], a => a + 1);
let result = filter(mapResult, a => a mod 2 === 0);
Js.log(result);
上面的範例 map
和 filter
為什麼要使用 send
呢?
也有另外一個比較漂亮的做法
[@bs.send] external map: (array('a), 'a => 'b) => array('b) = "";
[@bs.send] external filter: (array('a), 'a => 'b) => array('b) = "";
[|1, 2, 3|]
->map(a => a+1)
->filter(a => a mod 2 === 0)
->Js.log
但是這部分之後再探討
[@bs.val] [@bs.scope "Math"] external random: unit => float = "random";
let someNumber = random();
/**/
/* front end demo */
[@bs.val] [@bs.scope ("window", "location", "ancestorOrigins")] external length: int = "length";
let a = Some(5);
let b = None;
let JsNullable = Js.Nullable.null;
let JsUndefined = Js.Nullable.undefined;
let result1: Js.Nullable.t(string) = Js.Nullable.return("hello"); /* hello */
let result2: Js.Nullable.t(int) = Js.Nullable.fromOption(Some(10)); /* 10 */
let result3: option(int) = Js.Nullable.toOption(Js.Nullable.return(10)); /* 10 */
這一部份在後續章節也會做更詳細的討論
LeftPad.re
let default = (name: string, age: int) => Js.log({j|$name 年紀 $age|j});
ImportModule.re
[@bs.module "./LeftPad.bs"] external leftPad : (string, int) => string = "default";
leftPad("hello", 123);
因為 bsconfig.js
中的 suffix
設定為 .bs.js
所以當我們要 import 的時候需要加上 .bs
他編譯後的結果會是
var LeftPadBs = require("./LeftPad.bs");
LeftPadBs.default("hello", 123);
否則會找不到這個檔案
[@bs.module "path"] external dirname: string => string = "";
Js.log(dirname("/foo/bar/baz/asdf/quux"));
var Path = require("path");
console.log(Path.dirname("/foo/bar/baz/asdf/quux"));
@bs.module
會將模組引入
external
則是指定輸出的名稱 (在Reason
使用的名稱)
最後則是要引入的名稱,但是如果同名則可以設為空字串
使用 module path
中的 join
來做 demo
[@bs.module "path"] [@bs.splice]
external join : array(string) => string = "";
Js.log(join([|"/", "hello", "/", "world"|]));
bs.module
先指定來源 path
再加上 bs.splice
來告訴 Reason
他是一個具有不固定長度參數的 function
利用 array
的 長度是彈性的優點來做彈性的多參數處理
本來今天是要談談 BuckleScript 的 物件問題
看來只能明天了